using System;
using System.Collections.Generic;
using System.Linq;
using Mbs.Elements;

namespace Mbs.Modularity
{
    [Mbs.ComponentModel.Container.Component(Service=typeof(IModuleManagerPresenter))]
    public class ModuleManagerPresenter : Presenter<IModuleManagerView>, IModuleManagerPresenter
    {
        private readonly IModuleRepository ModuleRepository;
        private readonly IModuleManager ModuleManager;

        private readonly IElementCommand ElementStart;
        private readonly IElementCommand ElementStop;

        public ModuleManagerPresenter(
            IModuleRepository moduleRepository
            , IModuleManager moduleManager)
        {
            ModuleRepository = moduleRepository;
            ModuleManager = moduleManager;

            ElementStart = ModuleCommands.ModuleStart.Command();
            ElementStop = ModuleCommands.ModuleStop.Command();
        }

        protected override void OnInit()
        {
            Bind();
        }

        public override IEnumerator<IDisposable> Subscribe()
        {
            yield return ModuleCommands.ModuleSelectedChanged.Subscribe<EventArgs>((s, e) => OnCurrentChanged());
            yield return ModuleCommands.ModuleInstall.Subscribe<EventArgs>((s, e) => Install());
            yield return ModuleCommands.ModuleStart.Subscribe<EventArgs>((s, e) => Instance.Start());
            yield return ModuleCommands.ModuleStop.Subscribe<EventArgs>((s, e) => Instance.Stop());
        }

        private IModuleManagerPresenter Instance
        {
            get { return this as IModuleManagerPresenter; }
        }

        protected void OnCurrentChanged()
        {
            var current = View.CurrentItem;
            if (current != null)
            {
                switch (current.State)
                {
                    case ModuleState.Installed:
                        ElementStart.Enabled = true;
                        ElementStop.Enabled = false;
                        break;
                    case ModuleState.Actived:
                        ElementStart.Enabled = false;
                        ElementStop.Enabled = true;
                        break;
                }
            }
            else
            {
                ElementStart.Enabled = false;
                ElementStop.Enabled = false;
            }
        }

        public void Bind()
        {
            var id = 0;
            var modules = (from m in ModuleRepository.GetModules()
                           where m.Meta.AddIn != null && !m.Meta.AddIn.HideInManager
                           select new ModuleInfo (++id, m.Id,m.State,m.Meta)).ToArray();

            View.Bind(modules);

            if (modules == null || modules.Length == 0)
            {
                ElementStart.Enabled = false;
                ElementStop.Enabled = false;
            }
        }

        public void Install()
        {
            var moduleFile = View.Open();
            if (string.IsNullOrEmpty(moduleFile))
                return;

            var meta = ModuleMeta.Load(moduleFile, false);
            var module = ModuleManager.InstallModule(meta);

            Bind();

            View.CurrentId = module.Id;
        }

        public void Uninstall()
        {
            ModuleManager.StopModule(View.CurrentId);
            ModuleManager.UninstallModule(View.CurrentId);
            Bind();
        }

        void IModuleManagerPresenter.Start()
        {
            ModuleManager.StartModule(View.CurrentId);
            Bind();
        }

        void IModuleManagerPresenter.Stop()
        {
            ModuleManager.StopModule(View.CurrentId);
            Bind();
        }

    }
}
